﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Onshi.POS.AccesoDatos;
using Onshi.POS.AccesoDatos.Interfaces;
using Onshi.POS.Modelo.Entidades;
using Onshi.POS.Modelo.Objetos;

namespace Onshi.POS.Repositorios
{
    public class RepositorioVendedor : RepositorioEntidad<Vendedor, Int32>
    {
        #region Constructores

        public RepositorioVendedor()
            : base()
        {
            servicioDatosVendedor = new ServicioDatosVendedor();
            repositorioTipoIva = new RepositorioTipoIva();
            repositorioRubroVendedor = new RepositorioRubroVendedor();
            repositorioTipoDomicilio = new RepositorioTipoDomicilio();
            repositorioBarrio = new RepositorioBarrio();
            repositorioTipoTelefono = new RepositorioTipoTelefono();
            repositorioTipoMensajeriaInstantanea = new RepositorioTipoMensajeriaInstantanea();
            repositorioTipoComisionVendedor = new RepositorioTipoComisionVendedor();
        }

        #endregion

        #region Atributos

        private IServicioDatosVendedor servicioDatosVendedor;
        private RepositorioTipoIva repositorioTipoIva;
        private RepositorioRubroVendedor repositorioRubroVendedor;
        private RepositorioTipoDomicilio repositorioTipoDomicilio;
        private RepositorioTipoTelefono repositorioTipoTelefono;
        private RepositorioTipoMensajeriaInstantanea repositorioTipoMensajeriaInstantanea;
        private RepositorioBarrio repositorioBarrio;
        private RepositorioTipoComisionVendedor repositorioTipoComisionVendedor;

        #endregion

        #region Propiedades

        private IServicioDatosVendedor ServicioDatosVendedor
        {
            get { return servicioDatosVendedor; }
        }

        private RepositorioBarrio RepositorioBarrio
        {
            get { return repositorioBarrio; }
        }

        private RepositorioTipoTelefono RepositorioTipoTelefono
        {
            get { return repositorioTipoTelefono; }
        }

        private RepositorioTipoIva RepositorioTipoIva
        {
            get { return repositorioTipoIva; }
        }

        private RepositorioRubroVendedor RepositorioRubroVendedor
        {
            get { return repositorioRubroVendedor; }
        }

        private RepositorioTipoDomicilio RepositorioTipoDomicilio
        {
            get { return repositorioTipoDomicilio; }
        }

        private RepositorioTipoMensajeriaInstantanea RepositorioTipoMensajeriaInstantanea
        {
            get { return repositorioTipoMensajeriaInstantanea; }
        }

        private RepositorioTipoComisionVendedor RepositorioTipoComisionVendedor
        {
            get { return repositorioTipoComisionVendedor; }
        }

        #endregion

        #region Metodos

        protected override Vendedor FilaAEntidad(DataRow fila)
        {
            var vendedor = new Vendedor();
            vendedor.Id = (Int32)fila["IdVendedor"];
            vendedor.Codigo = (String)fila["Codigo"];
            vendedor.Nombre = (String)fila["Nombre"];
            vendedor.Cuit = (String)fila["Cuit"];
            vendedor.SitioWeb = (String)fila["SitioWeb"];
            vendedor.Email = (String)fila["Email"];
            vendedor.MensajeriaInstantanea = (String)fila["MensajeriaInstantanea"];
            vendedor.Comision = (Decimal)fila["Comision"];
            vendedor.ComisionMaxima = (Decimal)fila["ComisionMaxima"];
            vendedor.EstaEliminado = (Boolean)fila["EstaEliminado"];
            vendedor.Rubro = RepositorioRubroVendedor.DevolverPorId((Int32)fila["IdRubroVendedor"]);
            vendedor.TipoMensajeriaInstantanea = RepositorioTipoMensajeriaInstantanea.DevolverPorId((Byte)fila["IdTipoMensajeriaInstantanea"]);
            vendedor.TipoComision = RepositorioTipoComisionVendedor.DevolverPorId((Byte)fila["IdTipoComisionVendedor"]);
            if (fila.Table.Columns.Contains("TieneDomicilios"))
                vendedor.TieneDomicilios = (Boolean)fila["TieneDomicilios"];
            if (fila.Table.Columns.Contains("TieneImagen"))
                vendedor.TieneImagen = (Boolean)fila["TieneImagen"];
            if (fila.Table.Columns.Contains("TieneObservacion"))
                vendedor.TieneObservacion = (Boolean)fila["TieneObservacion"];
            if (fila.Table.Columns.Contains("TieneTelefonos"))
                vendedor.TieneTelefonos = (Boolean)fila["TieneTelefonos"];
            return vendedor;
        }

        private DetalleVendedor FilaADetalle(DataRow fila, Vendedor vendedor)
        {
            var detalle = new DetalleVendedor();
            detalle.Vendedor = vendedor;
            detalle.Observacion = (String)fila["Observacion"];
            if (fila["Imagen"] != DBNull.Value)
                detalle.Imagen = ManejoImagen.ByteAImagen((Byte[])fila["Imagen"]);
            return detalle;
        }

        private DomicilioVendedor FilaADomicilio(DataRow fila, Vendedor vendedor)
        {
            var domicilio = new DomicilioVendedor();
            domicilio.Vendedor = vendedor;
            domicilio.Id = (Int32)fila["IdDomicilioVendedor"];
            domicilio.Tipo = RepositorioTipoDomicilio.DevolverPorId((Byte)fila["IdTipoDomicilio"]);
            domicilio.Barrio = RepositorioBarrio.DevolverPorId((Int32)fila["IdBarrio"]);
            domicilio.Calle = (String)fila["Calle"];
            domicilio.Numero = (String)fila["Numero"];
            domicilio.Piso = (String)fila["Piso"];
            domicilio.Departamento = (String)fila["Departamento"];
            domicilio.Observacion = (String)fila["Observacion"];
            return domicilio;
        }

        private List<DomicilioVendedor> TablaAListaDomicilios(DataTable tabla, Vendedor vendedor)
        {
            var lista = new List<DomicilioVendedor>();
            foreach (DataRow fila in tabla.Rows)
                lista.Add(FilaADomicilio(fila, vendedor));
            return lista;
        }

        private TelefonoVendedor FilaATelefono(DataRow fila, Vendedor vendedor)
        {
            var telefono = new TelefonoVendedor();
            telefono.Vendedor = vendedor;
            telefono.Id = (Int32)fila["IdTelefonoVendedor"];
            telefono.Tipo = RepositorioTipoTelefono.DevolverPorId((Byte)fila["IdTipoTelefono"]);
            telefono.CodigoArea = (String)fila["CodigoArea"];
            telefono.Numero = (String)fila["Numero"];
            telefono.Observacion = (String)fila["Observacion"];
            return telefono;
        }

        private List<TelefonoVendedor> TablaAListaTelefonos(DataTable tabla, Vendedor vendedor)
        {
            var lista = new List<TelefonoVendedor>();
            foreach (DataRow fila in tabla.Rows)
                lista.Add(FilaATelefono(fila, vendedor));
            return lista;
        }

        public override Vendedor DevolverPorId(Int32 id)
        {
            var entidad = entidades.Where(x => x.Id == id).FirstOrDefault();
            if (entidad == null)
                using (var ds = ServicioDatosVendedor.Vendedores_DevolverPorId(id))
                    if (ds.Tables[0].Rows.Count != 0)
                    {
                        entidad = FilaAEntidad(ds.Tables[0].Rows[0]);
                        entidades.Add(entidad);
                    }
            return entidad;
        }

        public Vendedor DevolverPorIdConDetalleDomiciliosTelefonos(Int32 id)
        {
            var entidad = entidades.Where(x => x.Id == id
                && x.Detalle != null
                && x.Domicilios != null
                & x.Telefonos != null).FirstOrDefault();
            if (entidad == null)
                using (var ds = ServicioDatosVendedor.Vendedores_DevolverPorIdConDetalleDomiciliosTelefonos(id))
                    if (ds.Tables[0].Rows.Count != 0)
                    {
                        entidad = FilaAEntidad(ds.Tables[0].Rows[0]);
                        entidad.Detalle = FilaADetalle(ds.Tables[1].Rows[0], entidad);
                        entidad.Domicilios = TablaAListaDomicilios(ds.Tables[2], entidad);
                        entidad.Telefonos = TablaAListaTelefonos(ds.Tables[3], entidad);
                        entidades.Add(entidad);
                    }
            return entidad;
        }

        public Vendedor DevolverPorCodigo(String codigo)
        {
            var entidad = entidades.Where(x => x.Codigo == codigo).FirstOrDefault();
            if (entidad == null)
                using (var ds = ServicioDatosVendedor.Vendedores_DevolverPorCodigo(codigo))
                    if (ds.Tables[0].Rows.Count != 0)
                    {
                        entidad = FilaAEntidad(ds.Tables[0].Rows[0]);
                        entidades.Add(entidad);
                    }
            return entidad;
        }

        public Vendedor DevolverPorCodigoConDetalleDomiciliosTelefonos(String codigo)
        {
            var entidad = entidades.Where(x => x.Codigo == codigo
                && x.Detalle != null
                && x.Domicilios != null
                & x.Telefonos != null).FirstOrDefault();
            if (entidad == null)
                using (var ds = ServicioDatosVendedor.Vendedores_DevolverPorCodigoConDetalleDomiciliosTelefonos(codigo))
                    if (ds.Tables[0].Rows.Count != 0)
                    {
                        entidad = FilaAEntidad(ds.Tables[0].Rows[0]);
                        entidad.Detalle = FilaADetalle(ds.Tables[1].Rows[0], entidad);
                        entidad.Domicilios = TablaAListaDomicilios(ds.Tables[2], entidad);
                        entidad.Telefonos = TablaAListaTelefonos(ds.Tables[3], entidad);
                        entidades.Add(entidad);
                    }
            return entidad;
        }

        public List<Vendedor> DevolverTodos()
        {
            using (var ds = ServicioDatosVendedor.Vendedores_DevolverTodos())
                entidades = TablaALista(ds.Tables[0]);
            return entidades;
        }

        public void Insertar(Vendedor vendedor)
        {
            vendedor.Id = ServicioDatosVendedor.Vendedores_Insertar(vendedor.Rubro.Id, vendedor.TipoComision.Id, vendedor.TipoMensajeriaInstantanea.Id, vendedor.Codigo, vendedor.Nombre, vendedor.Cuit, vendedor.Comision, vendedor.ComisionMaxima, vendedor.Email, vendedor.SitioWeb, vendedor.MensajeriaInstantanea);
        }

        public void Modificar(Vendedor vendedor)
        {
            ServicioDatosVendedor.Vendedores_Modificar(vendedor.Id, vendedor.Rubro.Id, vendedor.TipoComision.Id, vendedor.TipoMensajeriaInstantanea.Id, vendedor.Codigo, vendedor.Nombre, vendedor.Cuit, vendedor.Comision, vendedor.ComisionMaxima, vendedor.Email, vendedor.SitioWeb, vendedor.MensajeriaInstantanea);
        }

        public void ModificarRubros(RubroVendedor rubroVendedor, RubroVendedor rubroVendedorNuevo)
        {
            ServicioDatosVendedor.Vendedores_ModificarRubrosVendedores(rubroVendedor.Id, rubroVendedorNuevo.Id);
        }

        public void Eliminar(Vendedor vendedor)
        {
            ServicioDatosVendedor.Vendedores_Eliminar(vendedor.Id);
            vendedor.EstaEliminado = true;
        }

        public void Habilitar(Vendedor vendedor)
        {
            ServicioDatosVendedor.Vendedores_Habilitar(vendedor.Id);
            vendedor.EstaEliminado = false;
        }

        public void EliminarDomiciliosPorVendedor(Vendedor vendedor)
        {
            ServicioDatosVendedor.DomiciliosVendedores_EliminarPorVendedor(vendedor.Id);
        }

        public void InsertarDomicilio(DomicilioVendedor domicilio)
        {
            domicilio.Id = ServicioDatosVendedor.DomiciliosVendedores_Insertar(domicilio.Vendedor.Id, domicilio.Tipo.Id, domicilio.Barrio.Id, domicilio.Calle, domicilio.Numero, domicilio.Piso, domicilio.Departamento, domicilio.Observacion);
        }

        public void EliminarTelefonosPorVendedor(Vendedor vendedor)
        {
            ServicioDatosVendedor.TelefonosVendedores_EliminarPorVendedor(vendedor.Id);
        }

        public void InsertarTelefono(TelefonoVendedor telefono)
        {
            telefono.Id = ServicioDatosVendedor.TelefonosVendedores_Insertar(telefono.Vendedor.Id, telefono.Tipo.Id, telefono.CodigoArea, telefono.Numero, telefono.Observacion);
        }

        public void InsertarDetalle(DetalleVendedor detalle)
        {
            ServicioDatosVendedor.VendedoresDetalles_Insertar(detalle.Vendedor.Id, detalle.Observacion, ManejoImagen.ImagenAByte(detalle.Imagen));
        }

        public void ModificarDetalle(DetalleVendedor detalle)
        {
            ServicioDatosVendedor.VendedoresDetalles_Modificar(detalle.Vendedor.Id, detalle.Observacion, ManejoImagen.ImagenAByte(detalle.Imagen));
        }

        public void ModificarDomiciliosBarrios(Barrio barrio, Barrio barrioNuevo)
        {
            ServicioDatosVendedor.DomiciliosVendedores_ModificarBarrios(barrio.Id, barrioNuevo.Id);
        }

        #endregion
    }
}